package com.jackstraw.jack_base.util;

import cn.hutool.core.io.IoUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * fileutil
 */
public class FileUtil {

    //文件分隔符
    public final static String separator = File.separator;

    public final static String oblique_line = "\\";

    public final static String back_slant = "/";

    /**
     * 返回基于传入路径的文件集合
     *
     * @param file
     * @param directory
     * @return
     */
    public static Map<String, List<File>> fileAll(File file, String directory) {
        Map<String, List<File>> fileMap = new HashMap<>();
        List<File> fileS = fileAll(file);
        if (fileS.size() == 1 && file.equals(fileS.get(0))) {
            if (ObjectUtils.isEmpty(fileMap.get(directory))) {
                fileMap.put(directory, new ArrayList<>());
            }
            fileMap.get(directory).add(file);
        } else {
            fileS.stream().forEach(fileSon -> {
                String path = directory.concat(separator).concat(fileSon.getParent().replace(file.getPath(), ""));
                while (path.indexOf(oblique_line) > -1 || path.indexOf(back_slant) > -1) {
                    path = path.replace(oblique_line, separator).replace(back_slant, separator);
                }
                if (ObjectUtils.isEmpty(fileMap.get(path))) {
                    fileMap.put(path, new ArrayList<>());
                }
                fileMap.get(path).add(fileSon);
            });
        }
        return fileMap;
    }


    /**
     * 获取传入路径下所有的文件
     *
     * @param file
     * @return
     */
    public static List<File> fileAll(File file) {
        List<File> fileAll = new ArrayList<>();
        if (file.isFile()) {
            fileAll.add(file);
        } else {
            List<File> fileList = Arrays.asList(file.listFiles());
            fileList.stream().forEach(fileSon -> {
                fileAll.addAll(fileAll(fileSon));
            });
        }
        return fileAll;
    }

    public static class FileUtilByHutool extends cn.hutool.core.io.FileUtil {
    }

    public static class FileUtilByCommonsIo extends org.apache.commons.io.FileUtils {
    }

    public static class IoUtilByHutool extends IoUtil {
        /**
         * 读取内容
         *
         * @param inputStream 文件IO流
         * @param charset     字符集
         * @return
         * @throws Exception
         */
        public static String readNote(InputStream inputStream, Charset charset) {
            try {
                return IoUtil.read(inputStream, charset);
            } finally {
                FileUtil.IoUtilByHutool.close(inputStream);
            }
        }

        /**
         * @param inputStream 文件IO流
         * @return
         * @throws Exception
         */
        public static String readNote(InputStream inputStream) {
            return readNote(inputStream, Charset.defaultCharset());
        }
    }

    public static class IoUtilByCommonsIo extends IOUtils {

    }


    /**
     * 获取传入路径的MD5值
     *
     * @param path
     * @return
     */
    public static String getMD5(String path) {
        BigInteger bi = null;
        try {
            byte[] buffer = new byte[1024 * 8];
            int len = 0;
            MessageDigest md = MessageDigest.getInstance("MD5");
            File f = new File(path);
            FileInputStream fis = new FileInputStream(f);
            while ((len = fis.read(buffer)) != -1) {
                md.update(buffer, 0, len);
            }
            fis.close();
            byte[] b = md.digest();
            bi = new BigInteger(1, b);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bi.toString(16);
    }

    /**
     * 获取传入路径的MD5值
     *
     * @param path
     * @return
     */
    public static String getMD5ByUtil(String path) {
        try {
            File file = new File(path);
            return DigestUtils.md5Hex(new FileInputStream(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
